/** 
* This lexer returns the tokens for the Gluck syntax analizer 
* 	Authors: 
*		Rezzano Sebastian
*		Bergez Pablo
*/	

/* Code, Import and Package Area */	

package gluck.lexico;
import gluck.sintactico.Parser;
import gluck.sintactico.ParserVal;
%%

/*no poner, hace q retorne un int en lugar de yytoken */
//%byaccj

/* Options and Declaration Area */

%public

%{
  private int comment_count = 0;
  private Parser yyparser;
  
  public Yylex(java.io.Reader r, Parser yyparser) {
    this(r);
    this.yyparser = yyparser;
  }
%} 

%line
%char
%column
%state COMMENT

/* Used for Debug */
%full
%debug


NONNEWLINE_WHITE_SPACE_CHAR=[\ \t\b\012]
NEW_LINE=\r|\n|\r\n
WHITE_SPACE_CHAR=[\n\r\ \t\b\012]
STRING_TEXT=(\\\"|[^\n\r\"]|\\{WHITE_SPACE_CHAR}+\\)*
COMMENT_TEXT=([^*/\n]|[^*\n]"/"[^*\n]|[^/\n]"*"[^/\n]|"*"[^/\n]|"/"[^*\n])*
COMMENT_LINE= \/\/.*{NEW_LINE}


ALPHA=[A-Za-z]
DIGIT=[0-9]
INTEGER_NUM= {DIGIT}+
REAL_NUM={DIGIT}+"."{DIGIT}+
ID= {ALPHA}({ALPHA}|{DIGIT})*



%% 

/* Rules Area */

<YYINITIAL> 	
{
  	"," 		|
  	":" 		|
  	";" 		|
	"(" 		|
	")" 		|
  	"[" 		|
	"]" 		|
	"{" 		|
	"}" 		|
	"+"	 	|
	"-"	 	|
	"/" 		|
	"*"		|
	"%"	 	|
	"!"		|
	"=" 		{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(yycharat(0),yytext(),yyline, yycolumn)); }
	("!="|"==") 	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.EQUAL_COMP,yytext(),yyline, yycolumn)); }
	("<"|"<="|">"|">=") 	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.UNEQUAL_COMP,yytext(),yyline,yycolumn)); }
	"->" 		{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.START_OUTPUT_PARAM,yytext(),yyline,yycolumn)); }
	"if"  		{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.IF,yytext(),yyline,yycolumn)); }
	"then"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.THEN,yytext(),yyline,yycolumn)); }
	"elseif"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.ELSEIF,yytext(),yyline,yycolumn)); }
	"else"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.ELSE,yytext(),yyline,yycolumn)); }
	"while"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.WHILE,yytext(),yyline,yycolumn)); }
	"loop"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.LOOP,yytext(),yyline,yycolumn)); }
	"ifquit"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.IFQUIT,yytext(),yyline,yycolumn)); }
	"ifnever"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.IFNEVER,yytext(),yyline,yycolumn)); }
	"quit"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.QUIT,yytext(),yyline,yycolumn)); }
	"function"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.FUNCTION,yytext(),yyline,yycolumn)); }
	"true"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.TRUE,yytext(),yyline,yycolumn)); }
	"false"  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.FALSE,yytext(),yyline,yycolumn)); }
	("and"|"or")  	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.LOGIC_OP,yytext(),yyline,yycolumn)); }

/* VER ESTOS TOKEN XQ LOS NECESITAMOS PARA ARMAR LA TABLA */

	"boolean"	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.TYPE,yytext(),yyline,yycolumn)); }
	"int"		{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.TYPE,yytext(),yyline,yycolumn)); }
	"real"		{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.TYPE,yytext(),yyline,yycolumn)); }
	"string" 	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.TYPE,yytext(),yyline,yycolumn)); }
  	

	{NONNEWLINE_WHITE_SPACE_CHAR}+ { }

	"/*" 		{ yybegin(COMMENT); comment_count++; }

	{COMMENT_LINE}	{ }

	\"{STRING_TEXT}\" 
			{
    			String str =  yytext().substring(1,yylength()-1);
	    		yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.STRING_TEXT,str,yyline,yycolumn));
  			}
  
	\"{STRING_TEXT} 
			{
    			String str =  yytext().substring(1,yytext().length());
	   			yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.UNCLOSEDSTR,str,yyline,yycolumn));
  			} 
  

	{REAL_NUM}	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.REAL_NUM,yytext(),yyline,yycolumn)); }  
	{INTEGER_NUM} 	{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.INTEGER_NUM,yytext(),yyline,yycolumn)); }  
	


	{ID} 		{ yyparser.setYylval( new ParserVal(yytext())); return (new Yytoken(Token.ID,yytext(),yyline,yycolumn)); }  
}

<COMMENT> 	
{
	"/*" 		{ comment_count++; }
	"*/" 		{ if (--comment_count == 0) yybegin(YYINITIAL); }
	{COMMENT_TEXT} 	{ }
	<<EOF>>		{ return (new Yytoken(Token.UNCLOSEDCOM,yytext(),yyline,yycolumn)); }
}


{NEW_LINE} 	{ }

. 	{return (new Yytoken(Token.UNMATCHED,yytext(),yyline,yycolumn));}

<<EOF>>	{ return (new Yytoken(Token.EOF,yytext(),yyline,yycolumn)); }  
